package com.home_school_platform.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.home_school_platform.entity.vo.*;
import com.home_school_platform.service.WeChatSubscriptionService;
import com.home_school_platform.util.WeChatSubscriptionUtil;
import com.home_school_platform.util.WeChatUtil;
import com.thoughtworks.xstream.XStream;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;



/**
 * 微信公众号业务逻辑层
 * @author 卓汉杰
 * */
@Service
public class WeChatSubscriptionServiceImpl implements WeChatSubscriptionService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;  //对字符串支持比较友好,不能存储对象
    @Autowired
    private RedisTemplate redisTemplate;  //存储对象



//    微信测试接口的自定义token
    private static final String TOKEN = "5555";

    private static final String GET_TOKEN_URL="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";

    //APPID
    private static final String APPID = "wxebcc69a3f6595db9";

    //appsecret
    private static final String APPSECRET = "fbc24509717e2d38f534f483ee8e1d91";

    /**
     * 获取token

     */
    public void getToken() {
        String url = GET_TOKEN_URL.replace("APPID", APPID).replace("APPSECRET", APPSECRET);
        String tokenStr = WeChatSubscriptionUtil.get(url);
        System.out.println(tokenStr);

        JSONObject jsonObject = JSONObject.parseObject(tokenStr);
        String token = jsonObject.getString("access_token");
        String expireIn = jsonObject.getString("expires_in");
        //创建token对象,保存在redis里面，并设计好过期时间。

        System.out.println(token);
        System.out.println(expireIn);

        redisTemplate.opsForValue().set("AccessToken",token,Long.valueOf(expireIn), TimeUnit.SECONDS);
    }


    /**
     * 公众号验证签名
     * @param signature 	微信加密签名，signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
     * @param timestamp 	时间戳
     * @param nonce 	随机数
     * @return 验证签名是否通过，通过返回true，
     */
    public boolean check(String signature,String timestamp, String nonce) {
        //1）将token、timestamp、nonce三个参数进行字典序排序
        String[] strs = new String[] {TOKEN,timestamp,nonce};
        Arrays.sort(strs);
        //2）将三个参数字符串拼接成一个字符串进行sha1加密
        String str = strs[0]+strs[1]+strs[2];
        String mysig = sha1(str);
        //3）开发者获得加密后的字符串可与signature对比，标识该请求来源于微信
        return mysig.equalsIgnoreCase(signature);
    }

    /**
     * 向处暴露的获取token的方法
     * @return
     * by 罗召勇 Q群193557337
     */
    public  String getAccessToken() {
        //获取redis 里面的微信公众号token，
        String token = (String) redisTemplate.opsForValue().get("AccessToken");

        //判断是否为空
        if (token == null || token.length() == 0){
            // 如果为空
            System.out.println("空");
            //重新获取token
            getToken();


            return (String) redisTemplate.opsForValue().get("AccessToken");
        }else {
            //如果不为空
            System.out.println("非空");
            return token;
        }
    }

    /**
     * 获取行业

     */

    public void get() {
        String at =getAccessToken();
        String url="https://api.weixin.qq.com/cgi-bin/template/get_industry?access_token="+at;
        String result = WeChatSubscriptionUtil.get(url);
        System.out.println(result);
    }



    /**
     * 进行sha1加密
     * @param str 加密文本
     * @return 加密结果
     */
    private  String sha1(String str) {
        try {
            //获取一个加密对象
            MessageDigest md = MessageDigest.getInstance("sha1");
            //加密
            byte[] digest = md.digest(str.getBytes());
            char[] chars= {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
            StringBuilder sb = new StringBuilder();
            //处理加密结果
            for(byte b:digest) {
                sb.append(chars[(b>>4)&15]);
                sb.append(chars[b&15]);
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解析xml数据包
     * @param is
     * @return xml的map
     */
    public  Map<String, String> parseRequest(InputStream is) {
        Map<String, String> map = new HashMap<>();
        SAXReader reader = new SAXReader();
        try {
            //读取输入流，获取文档对象
            Document document = reader.read(is);
            //根据文档对象获取根节点
            Element root = document.getRootElement();
            //获取根节点的所有的子节点
            List<Element> elements = root.elements();
            for(Element e:elements) {
                map.put(e.getName(), e.getStringValue());
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return map;
    }


    /**
     * 用于处理所有的事件和消息的回复
     * @param requestMap
     * @return 返回的是xml数据包
     * by 罗召勇 Q群193557337
     */
    public  String getRespose(Map<String, String> requestMap) {
        BaseMessageVO msg=null;
        String msgType = requestMap.get("MsgType");
        switch (msgType) {
            //处理文本消息
            case "text":
                msg=dealTextMessage(requestMap);
                break;
            case "image":

                break;
            case "voice":

                break;
            case "video":

                break;
            case "shortvideo":

                break;
            case "location":

                break;
            case "link":

                break;
            case "event":

                break;
            default:
                break;
        }
        //把消息对象处理为xml数据包
        if(msg!=null) {
            return beanToXml(msg);
        }
        return null;
    }

    /**
     * 把消息对象处理为xml数据包
     * @param msg
     * @return
     * by 罗召勇 Q群193557337
     */
    private static String beanToXml(BaseMessageVO msg) {
        XStream stream = new XStream();
        //设置需要处理XStreamAlias("xml")注释的类
        stream.processAnnotations(TextMessageVO.class);
        String xml = stream.toXML(msg);
        return xml;
    }

    /**
     * 处理文本消息
     * @param requestMap
     * @return
     */
    private  BaseMessageVO dealTextMessage(Map<String, String> requestMap) {
        String msg = requestMap.get("Content");
        String resp = "hhhhhhhhhhhhhhhhhh";
        TextMessageVO tm = new TextMessageVO(requestMap, resp);
        return tm;
    }


    /**
     * 设置行业
     */

    public void set() {
        //获取
        String at = getAccessToken();
        String url="https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token="+at;
        String data="{\n" +
                "          \"industry_id1\":\"1\",\n" +
                "          \"industry_id2\":\"4\"\n" +
                "       }";
        String result = WeChatSubscriptionUtil.post(url, data);
        System.out.println(result);
    }



/**
 * 微信公众号菜单 json
 * */
    private String testButton() {
        // 菜单对象
        Button btn = new Button();
        // 第一个一级菜单
        btn.getButton().add(new ViewButton("首页", "http://www.baidu.com"));
        // 第二个一级菜单
        btn.getButton().add(new ViewButton("商城", "http://www.baidu.com"));
        // 创建第三个一级菜单
        SubButton sb = new SubButton("快速入口");
        // 为第三个一级菜单增加子菜单

        sb.getSub_button().add(new ViewButton("消息", "http://www.baidu.com"));
        sb.getSub_button().add(new ViewButton("作业", "http://www.baidu.com"));
        sb.getSub_button().add(new ViewButton("成绩", "http://www.baidu.com"));
        sb.getSub_button().add(new ViewButton("缴费", "http://www.baidu.com"));
        sb.getSub_button().add(new ViewButton("道闸", "http://www.baidu.com"));

        // 加入第三个一级菜单
        btn.getButton().add(sb);
        // 转为json
        Object jsonObject = JSONObject.toJSON(btn);
        return jsonObject.toString();
    }


    /**
     * 设置菜单
     * */
    public  void CreateMenu() {

        String s = testButton();

        //准备url
        String url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
        url = url.replace("ACCESS_TOKEN", getAccessToken());
        //发送请求
        String result = WeChatSubscriptionUtil.post(url, s);
        System.out.println(result);

    }

    /**
     * 发送模板消息
     * */
    public void sendTemplateMessage(WeChatSubscriptionMessage weChatSubscriptionMessage) {
        String at = getAccessToken();
        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+at;
        String data="{\n" +
                "           \"touser\":\""+weChatSubscriptionMessage.getOpenid()+ "\",\n" +
                "           \"template_id\":\"C3zaph-cX1ehM9vLStTz2R3zXlZAc2tlF_Yf6hUBZYI\",         \n" +
                " \"url\":\"https://www.baidu.com/\",\n" +
                "           \"data\":{\n" +
                "                   \"type\": {\n" +
                "                       \"value\":\""+weChatSubscriptionMessage.getType()+"！\",\n" +
                "                       \"color\":\"#abcdef\"\n" +
                "                   },\n" +
                "                   \"title\":{\n" +
                "                       \"value\":\""+weChatSubscriptionMessage.getTitle()+"\",\n" +
                "                       \"color\":\"#fff000\"\n" +
                "                   }\n" +
                "           }\n" +
                "       }";
        String result = WeChatSubscriptionUtil.post(url, data);
        System.out.println(result);
    }


}
